package com.suray.basic.wcs.plc.config.resolver;

import com.alibaba.fastjson.JSON;
import com.suray.basic.wcs.plc.core.ModbusUtil;
import com.suray.basic.wcs.plc.entity.PlcLogDB;
import com.suray.basic.wcs.plc.oper.impl.PlcOperImpl;
import com.suray.basic.wcs.plc.service.impl.PlcLogServiceImpl;
import com.suray.commin.core.utils.SpringContextHolder;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;
import java.util.Date;

public class PlcInterceptor implements MethodInterceptor {

    PlcLogServiceImpl plcLogService = SpringContextHolder.getBean(PlcLogServiceImpl.class);

    @Override
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        // 注解对象
        PlcAnnotation interfaceLog = method.getAnnotation(PlcAnnotation.class);
        // plc类中没有注解的方法不走代理
        if(interfaceLog == null){
            return methodProxy.invokeSuper(proxy, args);
        }

        PlcLogDB plcLogdb = new PlcLogDB();
        if (proxy instanceof PlcOperImpl) {
            PlcOperImpl plcOper = (PlcOperImpl)proxy;
            plcLogdb.setDeviceName(plcOper.getPlc().getPlcParam().getPlcName());
            plcLogdb.setPlcMethodDetail(interfaceLog.value());
            plcLogdb.setPlcSendParams(JSON.toJSONString(args));
        } else if (proxy instanceof ModbusUtil) {
            ModbusUtil modbusUtil = (ModbusUtil) proxy;
            plcLogdb.setDeviceName(modbusUtil.getPlcName());
            plcLogdb.setPlcMethodDetail((String) args[0]);
            plcLogdb.setPlcSendParams(JSON.toJSONString(args[4]));
        } else {
            return methodProxy.invokeSuper(proxy, args);
        }
        // 返回结果初始化
        Object ret;
        long startTime = System.currentTimeMillis();
        long endTime;
        try {
            ret = methodProxy.invokeSuper(proxy, args);
        } catch (Exception e) { // 捕获到方法异常记录到ex中，再抛出异常防止对正常业务的影响
            endTime = System.currentTimeMillis();
            plcLogdb.setSendTime(new Date(startTime));
            plcLogdb.setUseTime(endTime - startTime);
            plcLogdb.setPlcReturnParams(JSON.toJSONString(e == null ? "" : e));
            // 异常信息保存到日志表
            plcLogService.setInterfaceLog(plcLogdb);
            throw e;
        }
        endTime = System.currentTimeMillis();
        plcLogdb.setSendTime(new Date(startTime));

        plcLogdb.setUseTime(endTime - startTime);
        plcLogdb.setPlcReturnParams(JSON.toJSONString(ret == null ? "无" : ret));

        // 日志记录保存到表
        plcLogService.setInterfaceLog(plcLogdb);

        return ret;
    }
}


